home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / watcom / w_modey / yprim.cpp < prev    next >
C/C++ Source or Header  |  1994-02-19  |  9KB  |  392 lines

  1. #include <conio.h>
  2. #include <dos.h>
  3. #include <mem.h>
  4. #include <stdio.h>
  5.  
  6. #include "yprim.hpp"
  7.  
  8. BYTE *RowsY[200];
  9. BYTE Yfont[2048];
  10.  
  11.  
  12. void
  13. set80x25(void)
  14. {
  15.     union REGS r;
  16.     r.x.eax = 0x0003;
  17.  
  18.     int386(0x10, &r, &r);
  19. }
  20.  
  21.  
  22. void
  23. set320x200x256(void)
  24. {
  25.     union REGS r;
  26.     int i;
  27.  
  28.     r.x.eax = 0x0013;
  29.  
  30.     int386(0x10, &r, &r);
  31.  
  32.     for (i=0; i < 200; i++) {
  33.         RowsY[i] = (unsigned char *)((0xA000 << 4) + (320 * i));
  34.     }
  35. }
  36.  
  37.  
  38. void
  39. wait_for_retrace(void)
  40. {
  41.     while (!(inp(0x3DA) & 0x08));
  42. }
  43.  
  44.  
  45. void
  46. clear(BYTE color)
  47. {
  48.     memset((unsigned char *)(0xA000 << 4), color, 64000L);
  49. }
  50.  
  51.  
  52. void
  53. putpixel(COORD x, COORD y, BYTE color)
  54. {
  55.     *(RowsY[y] + x) = color;
  56. }
  57.  
  58.  
  59. inline void
  60. internal_putpixel(COORD x, COORD y, BYTE color)
  61. {
  62.     *(RowsY[y] + x) = color;
  63. }
  64.  
  65.  
  66. BYTE
  67. getpixel(COORD x, COORD y)
  68. {
  69.     return *(RowsY[y] + x);
  70. }
  71.  
  72.  
  73. inline void
  74. internal_vert_line(int x, int top_y, int len, BYTE color)
  75. {
  76.     BYTE *ptr;
  77.  
  78.     ptr = RowsY[top_y] + x;
  79.  
  80.     while (len--) {
  81.         *ptr = color;
  82.         ptr += 320;
  83.     }
  84. }
  85.  
  86.  
  87. inline void
  88. internal_horiz_line(int left_x, int y, int len, BYTE color)
  89. {
  90.     memset((RowsY[y] + left_x), color, len);
  91. }
  92.  
  93.  
  94. void
  95. box(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)
  96. {
  97.     int xsize, ysize;
  98.  
  99.     xsize = (x2 - x1) + 1;
  100.     internal_horiz_line(x1, y1, xsize, color);
  101.     internal_horiz_line(x1, y2, xsize, color);
  102.  
  103.     y1++;
  104.     ysize = (y2 - y1);
  105.  
  106.     internal_vert_line(x1, y1, ysize, color);
  107.     internal_vert_line(x2, y1, ysize, color);
  108. }
  109.  
  110.  
  111. void
  112. filledbox(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)
  113. {
  114.     int xsize, ysize;
  115.  
  116.     xsize = (x2 - x1) + 1;
  117.     ysize = (y2 - y1) + 1;
  118.  
  119.     while (ysize--) {
  120.         internal_horiz_line(x1, y1++, xsize, color);
  121.     }
  122. }
  123.  
  124.  
  125. void
  126. line(COORD lx1, COORD ly1, COORD lx2, COORD ly2, BYTE color)
  127. {
  128.     unsigned char *ptr;
  129.     unsigned char *ptr2;
  130.     unsigned long ErrorAcc, ErrorAdj;
  131.     int DeltaX, DeltaY, XDir, temp;
  132.  
  133.     // Line drawing with Bresenham's integer line-drawing algorithm for speed
  134.     // Conversion to symmetrical Bresenham by David Boeren
  135.  
  136.     // Make sure the line runs top to bottom
  137.     if (ly1 > ly2) {
  138.         temp = lx1; lx1 = lx2; lx2 = temp;
  139.         temp = ly1; ly1 = ly2; ly2 = temp;
  140.     }
  141.  
  142.     DeltaX = (lx2 - lx1);
  143.  
  144.     if (DeltaX >= 0) {
  145.         XDir = 1;
  146.     } else {
  147.         XDir = -1;
  148.         DeltaX = -DeltaX;  // Make DeltaX positive
  149.     }
  150.  
  151.     DeltaY = (ly2 - ly1);
  152.  
  153.     if (DeltaY == 0) {
  154.         // Horizontal Line (and one pixel lines)
  155.         if (XDir == 1) {
  156.             memset((RowsY[ly1] + lx1), color, (DeltaX + 1));
  157.         } else {
  158.             memset((RowsY[ly1] + lx2), color, (DeltaX + 1));
  159.         }
  160.         return;
  161.     }
  162.  
  163.     if (DeltaX == 0) {
  164.         // Vertical Line
  165.         internal_vert_line(lx1, ly1, (DeltaY + 1), color);
  166.         return;
  167.     }
  168.  
  169.     // Draw the initial pixels
  170.      ptr  = RowsY[ly1] + lx1;
  171.     *ptr  = color;
  172.      ptr2 = RowsY[ly2] + lx2;
  173.     *ptr2 = color;
  174.  
  175.     // initialize line error accumulator to .5, so we can
  176.     // advance when we get halfway to the next pixel
  177.     ErrorAcc = 0x8000;
  178.  
  179.     // Is this an X-major or a Y-major line?
  180.     if (DeltaY > DeltaX) {
  181.         // Y-major line; calculate 16-bit fixed point fractional part
  182.         // of a pixel that X advances each time Y advances 1 pixel
  183.         ErrorAdj = ((((unsigned long)DeltaX << 17) /
  184.                       (unsigned long)DeltaY) + 1) >> 1;
  185.  
  186.         // Draw all pixels between the first and last
  187.         DeltaY = (DeltaY >> 1);
  188.         while (DeltaY--) {
  189.             // calculate error for this pixel
  190.             ErrorAcc += ErrorAdj;
  191.  
  192.             if (ErrorAcc & ~0xFFFFL) {
  193.                 // clear integer part of result
  194.                 ErrorAcc &= 0xFFFFL;
  195.  
  196.                 // The error accumulator turned over, so advance the X coord
  197.                 ptr  += XDir;
  198.                 ptr2 -= XDir;
  199.             }
  200.  
  201.              ptr  += 320;
  202.             *ptr   = color;
  203.              ptr2 -= 320;
  204.             *ptr2  = color;
  205.         }
  206.     } else {
  207.         // It's an X-major line; calculate 16-bit fixed point fractional
  208.         // part of a pixel that Y advances each time X advances 1 pixel
  209.         ErrorAdj = ((((unsigned long)DeltaY << 17) /
  210.                       (unsigned long)DeltaX) + 1) >> 1;
  211.  
  212.         // Draw all remaining pixels
  213.         DeltaX = (DeltaX >> 1);
  214.         while (DeltaX--) {
  215.             // calculate error for this pixel
  216.             ErrorAcc += ErrorAdj;
  217.  
  218.             if (ErrorAcc & ~0xFFFFL) {
  219.                 // clear integer part of result
  220.                 ErrorAcc &= 0xFFFFL;
  221.  
  222.                 // The error accumulator turned over, so advance the Y coord
  223.                 ptr  += 320;
  224.                 ptr2 -= 320;
  225.             }
  226.  
  227.              ptr  += XDir;
  228.             *ptr   = color;
  229.              ptr2 -= XDir;
  230.             *ptr2  = color;
  231.         }
  232.     }
  233. }
  234.  
  235.  
  236. void
  237. circle(COORD x, COORD y, DIST r, BYTE color)
  238. {
  239.     int ix, iy, d, deltaE, deltaSE;
  240.  
  241.     ix = 0;
  242.     iy = r;
  243.     d = 1 - r;
  244.     deltaE = 3;
  245.     deltaSE = (-2 * r) + 5;
  246.  
  247.     internal_putpixel(x + ix, y + iy, color);
  248.     internal_putpixel(x + ix, y - iy, color);
  249.     internal_putpixel(x + iy, y + ix, color);
  250.     internal_putpixel(x + iy, y - ix, color);
  251.     internal_putpixel(x - ix, y + iy, color);
  252.     internal_putpixel(x - ix, y - iy, color);
  253.     internal_putpixel(x - iy, y + ix, color);
  254.     internal_putpixel(x - iy, y - ix, color);
  255.  
  256.     while (iy > ix++) {
  257.         if (d < 0) {
  258.             d += deltaE;
  259.             deltaE += 2;
  260.             deltaSE += 2;
  261.         } else {
  262.             d += deltaSE;
  263.             deltaE += 2;
  264.             deltaSE += 4;
  265.             iy--;
  266.         }
  267.  
  268.         internal_putpixel(x + ix, y + iy, color);
  269.         internal_putpixel(x + ix, y - iy, color);
  270.         internal_putpixel(x + iy, y + ix, color);
  271.         internal_putpixel(x + iy, y - ix, color);
  272.         internal_putpixel(x - ix, y + iy, color);
  273.         internal_putpixel(x - ix, y - iy, color);
  274.         internal_putpixel(x - iy, y + ix, color);
  275.         internal_putpixel(x - iy, y - ix, color);
  276.     }
  277. }
  278.  
  279.  
  280. void
  281. filledcircle(COORD x, COORD y, DIST r, BYTE color)
  282. {
  283.     int ix, iy, d, deltaE, deltaSE;
  284.  
  285.     ix = 0;
  286.     iy = r;
  287.     d = 1 - r;
  288.     deltaE = 3;
  289.     deltaSE = (-2 * r) + 5;
  290.  
  291.     internal_horiz_line(x - ix, y + iy, (ix << 1) + 1, color);
  292.     internal_horiz_line(x - ix, y - iy, (ix << 1) + 1, color);
  293.     internal_horiz_line(x - iy, y + ix, (iy << 1) + 1, color);
  294.     internal_horiz_line(x - iy, y - ix, (iy << 1) + 1, color);
  295.  
  296.     while (iy > ix++) {
  297.         if (d < 0) {
  298.             d += deltaE;
  299.             deltaE += 2;
  300.             deltaSE += 2;
  301.         } else {
  302.             d += deltaSE;
  303.             deltaE += 2;
  304.             deltaSE += 4;
  305.             iy--;
  306.         }
  307.  
  308.         internal_horiz_line(x - ix, y + iy, (ix << 1) + 1, color);
  309.         internal_horiz_line(x - ix, y - iy, (ix << 1) + 1, color);
  310.         internal_horiz_line(x - iy, y + ix, (iy << 1) + 1, color);
  311.         internal_horiz_line(x - iy, y - ix, (iy << 1) + 1, color);
  312.     }
  313. }
  314.  
  315.  
  316. int
  317. loadfont(char *fname)
  318. {
  319.     FILE *fp;
  320.  
  321.     fp = fopen(fname, "rb");
  322.  
  323.     if (fp == NULL) {
  324.         return 0;
  325.     } else {
  326.         fread(Yfont, 8, 256, fp);
  327.         fclose(fp);
  328.         return 1;
  329.     }
  330. }
  331.  
  332.  
  333. void
  334. putch(COORD x, COORD y, char c, BYTE color)
  335. {
  336.     short int i;
  337.     BYTE temp;
  338.     BYTE *vga_ptr;
  339.     BYTE *font_ptr;
  340.  
  341.     vga_ptr = RowsY[y << 3] + (x << 3);
  342.     font_ptr = Yfont + (c << 3);
  343.  
  344.     i=8;
  345.     while (i--) {
  346.         temp = *font_ptr++;
  347.         if (temp & 0x01) {
  348.             *vga_ptr = color;
  349.         }
  350.         vga_ptr++;
  351.         if (temp & 0x02) {
  352.             *vga_ptr = color;
  353.         }
  354.         vga_ptr++;
  355.         if (temp & 0x04) {
  356.             *vga_ptr = color;
  357.         }
  358.         vga_ptr++;
  359.         if (temp & 0x08) {
  360.             *vga_ptr = color;
  361.         }
  362.         vga_ptr++;
  363.         if (temp & 0x10) {
  364.             *vga_ptr = color;
  365.         }
  366.         vga_ptr++;
  367.         if (temp & 0x20) {
  368.             *vga_ptr = color;
  369.         }
  370.         vga_ptr++;
  371.         if (temp & 0x40) {
  372.             *vga_ptr = color;
  373.         }
  374.         vga_ptr++;
  375.         if (temp & 0x80) {
  376.             *vga_ptr = color;
  377.         }
  378.  
  379.         vga_ptr += 313;  // 320 - 7
  380.     }
  381. }
  382.  
  383.  
  384. void
  385. putstring(COORD x, COORD y, char *str, BYTE color)
  386. {
  387.     while (*str) {
  388.         putch(x++,y,*str++,color);
  389.     }
  390. }
  391.  
  392.